﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace UtilsExtensionsAndHelpers.Utils
{
    public interface IMsSqlQuery : IQuery, IRow { }

    public interface IQuery: IDisposable
    {
        /*
        void SetConstructorArgs(string connectionString);
        void SetConstructorArgs(string connectionString, int timeOut);
        //void SetConstructorArgs(string connectionString, int timeOut, bool usePersistentConnection);
        void SetConstructorArgs(SqlConnection connection);
        void SetConstructorArgs(SqlConnection connection, int timeOut);
        //void SetConstructorArgs(SqlConnection connection, int timeOut, bool usePersistentConnection);
        */

        T ExecuteSqlForOne<T>(String sql, Func<IRow, T> conversionAction);
        T ExecuteSqlForOne<T>(String sql, IEnumerable<SqlParameter> parameters, Func<IRow, T> conversionAction);
        T ExecuteProcedureForOne<T>(String sql, Func<IRow, T> conversionAction);
        T ExecuteProcedureForOne<T>(String sql, IEnumerable<SqlParameter> parameters, Func<IRow, T> conversionAction);

        IEnumerable<T> ExecuteSqlForMany<T>(String sql, Func<IRow, T> conversionAction);
        IEnumerable<T> ExecuteSqlForMany<T>(String sql, IEnumerable<SqlParameter> parameters, Func<IRow, T> conversionAction);
        IEnumerable<T> ExecuteProcedureForMany<T>(String sql, Func<IRow, T> conversionAction);
        IEnumerable<T> ExecuteProcedureForMany<T>(String sql, IEnumerable<SqlParameter> parameters, Func<IRow, T> conversionAction);

        void ExecuteSqlNoResult(String sql);
        void ExecuteSqlNoResult(String sql, IEnumerable<SqlParameter> parameters);
        void ExecuteProcedureNoResult(String sql);
        void ExecuteProcedureNoResult(String sql, IEnumerable<SqlParameter> parameters);
    }

    public interface IRow
    {
        /// <summary>
        /// Returns the ordinal column number for a named column.
        /// The ordinal is cached so unlike SqlDataReader.GetOrdinal() it's not a performance hit to call it inside a loop.
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        int this[string column] { get; }

        bool GetBoolean(string column);
        byte GetByte(string column);
        DateTime GetDateTime(string column);
        decimal GetDecimal(string column);
        double GetDouble(string column);
        float GetFloat(string column);
        short GetInt16(string column);
        int GetInt32(string column);
        long GetInt64(string column);
        string GetString(string column);
        bool IsDBNull(string column);
        bool? GetNullableBoolean(string column);
        byte? GetNullableByte(string column);
        DateTime? GetNullableDateTime(string column);
        decimal? GetNullableDecimal(string column);
        double? GetNullableDouble(string column);
        float? GetNullableFloat(string column);
        short? GetNullableInt16(string column);
        int? GetNullableInt32(string column);
        long? GetNullableInt64(string column);
    }
}
